﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Security.Cryptography;

namespace Indt.Components
{
    public static class StorageList<T>
    {
        public static bool Save(List<T> List, string Name)
        {
            bool bReturn = false;

            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.Indent = true;

            IsolatedStorageFileStream stream = null;

            try
            {
                using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (stream = myIsolatedStorage.OpenFile(Name, FileMode.Create))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
                        using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
                        {
                            serializer.Serialize(xmlWriter, List);
                            bReturn = true;
                        }
                    }
                }
                Debug.WriteLine("Save List");
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error saving: " + e.ToString() + ", Message:" + e.Message + ", Object: " + e.InnerException);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                }
            }

            return bReturn;
        }

        public static List<T> Load(string Name)
        {
            List<T> List = new List<T>();
            IsolatedStorageFileStream stream = null;

            try
            {
                using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (stream = myIsolatedStorage.OpenFile(Name, FileMode.Open))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(List<T>));

                        List = (List<T>)serializer.Deserialize(stream);
                    }
                }
                Debug.WriteLine("Load List");
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error loading: " + e.ToString() + ", Message:" + e.Message + ", Object: " + e.InnerException);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                }
            }
            return List;
        }
    }

    public static class StorageData
    {
        private static IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();

        public static void SaveData(string data, string filePath)
        {
            // Convert the data to byte[]
            byte[] dataByte = Encoding.UTF8.GetBytes(data);
            byte[] ProtectedDataByte = null;

            try
            {
                // Encrypt data using the Protect() method.
                ProtectedDataByte = ProtectedData.Protect(dataByte, null);
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error encrypting: " + e.ToString() + ", Message:" + e.Message + ", Object: " + e.InnerException);
            }

            if (ProtectedDataByte != null)
            {
                // Store the encrypted PIN in isolated storage
                StoreData(ProtectedDataByte, filePath);
            }
        }

        private static void StoreData(byte[] storeData, string filePath)
        {
            try
            {
                // Write data to storage
                IsolatedStorageFileStream writestream = new IsolatedStorageFileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write, file);
                Stream writer = new StreamWriter(writestream).BaseStream;
                writer.Write(storeData, 0, storeData.Length);
                writer.Close();
                writestream.Close();
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error saving: " + e.ToString() + ", Message:" + e.Message + ", Object: " + e.InnerException);
            }
        }

        public static string LoadData(string filePath)
        {
            if (file.FileExists(filePath) == false)
                SaveData(string.Empty, filePath);

            try
            {
                //Receive the encrypted info
                byte[] ProtectedlInfo = LoadEncryptedInfo(filePath);

                // Decrypt info.
                byte[] lInfoByte = ProtectedData.Unprotect(ProtectedlInfo, null);

                //Convert the info to string
                return Encoding.UTF8.GetString(lInfoByte, 0, lInfoByte.Length);
            }

            catch (Exception e)
            {
                string error = "Error reading: " + e.ToString() + ", Message:" + e.Message + ", Object: " + e.InnerException;
                Debug.WriteLine(error);
                return error;
            }
        }

        private static byte[] LoadEncryptedInfo(string filePath)
        {
            byte[] Array = { };

            if (!file.FileExists(filePath))
            {
                Debug.WriteLine("Arquivo não existe: " + filePath);
            }
            else
            {
                IsolatedStorageFileStream readstream = new IsolatedStorageFileStream(filePath, System.IO.FileMode.Open, FileAccess.Read, file);

                Stream reader = new StreamReader(readstream).BaseStream;
                Array = new byte[reader.Length];

                reader.Read(Array, 0, Array.Length);
                reader.Close();
                readstream.Close();
            }

            return Array;
        }
    }
}